package model

import (
	"crypto/md5"
	"encoding/hex"
	"errors"
	"fmt"
	"gorm.io/gorm"
	"gorm.io/gorm/clause"
	"math/rand"
	"server/common"
	"strconv"
	"time"
)

type UserInfo struct {
	desc string `gorm:"column:desc;type:longtext;"` //自我介绍
}

type BaseRole struct {
	Role string `gorm:"column:role;type:ENUM('superadmin','admin','user','guest');default:'user''" json:"role"`
}

// 过滤密码
type BaseUser struct {
	Model
	Name string `gorm:"column:name;not null;type:varchar(16);unique" json:"username"`

	BaseRole
	Email string `gorm:"column:email;type:varchar(50)" json:"email"`
}

type User struct {
	BaseUser
	Token    string `gorm:"column:token;type:varchar(256);"`                            //每个用户可以生成一个token用于api接口访问
	PassWord string `gorm:"column:password;not null;type:varchar(32);" json:"password"` //设置字段大小为255
}

type Owner struct {
	Model
	Name string `gorm:"column:name;not null;type:varchar(16);unique" json:"username"`
	BaseRole
	Token string `gorm:"column:token"`

	Projects  []Project  `gorm:"many2many:user_project;ForeignKey:ID;References:ID" json:"projects"`
	Tasks     []Task     `gorm:"many2many:user_task;ForeignKey:ID;References:ID" json:"tasks"`
	PipeLines []PipeLine `gorm:"many2many:user_pipeline;ForeignKey:ID;References:ID" json:"pipelines"`
}

func (u *Owner) Info() {
	if err := common.DB.Where("name = ?", u.Name).Or("id = ?", u.ID).Preload(clause.Associations).Find(&u).Error; err != nil {
		fmt.Println(err.Error())
		return
	}
	return
}

func (u *User) Create() error {
	u.Token = generateToken()
	if err := common.DB.Omit(clause.Associations).Debug().Create(&u); err != nil {
		return err.Error
	}
	return nil
}

func (user *User) List() ([]User, int64) {
	var users []User
	var count int64
	err := common.DB.Where("name != ?", "admin").Find(&users).Count(&count)
	if err != nil {
		return users, count
	}
	return users, count
}

// 获取用户信息
func (user *User) Info() {
	err := common.DB.Model(&User{}).Where("name = ?", user.Name).First(&user)
	if err != nil {
		return
	}
	return
}

func (user *User) Update() error {
	if err := common.DB.Debug().Where("id = ?", user.ID).Updates(&user).Error; err != nil {
		return err
	}
	return nil
}

func (u *User) BeforeDelete(tx *gorm.DB) error {
	if u.Name == "admin" {
		return errors.New("admin user not allowed to delete")
	}
	return nil
}

func (user *Owner) Delete() error {
	if err := common.DB.Model(&user).Association("Projects").Clear(); err != nil {
		fmt.Println(err)
		return err
	}

	if err := common.DB.Delete(&user).Error; err != nil {
		fmt.Println(err)
		return err
	}
	return nil
}

func (user *User) TableName() string {
	return "user_auth"
}

func (user *Owner) TableName() string {
	return "user_auth"
}

var CharStr = "zxcvbnmasdfghjklqwertyuiopZXCVBNMASDFGHJKLQWERTYUIOP1234567890+@"

func (user *User) GenerateToken() error {
	user.Token = generateToken()
	if err := common.DB.Where("name = ?", user.Name).Updates(&user).Error; err != nil {
		return err
	}
	return nil
}

func generateToken() string {
	a := time.Now().UnixNano()
	str1 := strconv.FormatInt(a, 10)
	result := make([]byte, 128)
	for i := 0; i < 128; i++ {
		result[i] = CharStr[rand.Intn(len(CharStr))]
	}
	str1 += string(result)
	m := md5.New()
	m.Write([]byte(str1))
	return hex.EncodeToString(m.Sum(nil))
}

func QueryToken(token string) User {
	var user = User{}
	if err := common.DB.Where("token = ?", token).First(&user).Error; err != nil {
		return user
	}
	return user
}
